/**
 * 
 */
package fr.toussna.dao;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.Assert;
import org.testng.annotations.Test;

import fr.toussna.entity.Article;
import fr.toussna.entity.DomainEntity;
import fr.toussna.exception.ObjectNotFoundException;
import fr.toussna.utils.EntityFactory;

/**
 * 
 * Testing ArticleDAO
 * 
 * @author My
 * 
 */
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
@Test(suiteName = "ArticleDAOTestCase")
public class ArticleDAOTestCase extends AbstractTestNGSpringContextTests {

	private static final Log LOGGER = LogFactory.getLog(ArticleDAOTestCase.class.getName());

	@Autowired
	@Qualifier("articledao")
	private ArticleDAO articledao;

	@Autowired
	@Qualifier("entityfactory")
	private EntityFactory entityfactory;

	@Test
	public void insert() {
		LOGGER.info("insert - starting...");
		Article article = (Article) entityfactory.createDomainEntity("article");
		Number id = articledao.insert(article);
		try {
			Assert.assertNotNull(id);
			Assert.assertEquals(article.getTitle(), ((Article) articledao.select(id)).getTitle());
			Assert.assertEquals(article.getContent(), ((Article) articledao.select(id)).getContent());
			Assert.assertEquals(article.getDate(), ((Article) articledao.select(id)).getDate());
			article.setId((Long) id);
			articledao.delete(article);
		} catch (Exception e) {
		}
		LOGGER.info("insert - end.");
	}

	@Test
	public void select() {
		LOGGER.info("select - starting...");
		Article article = (Article) entityfactory.createDomainEntity("article");
		Article article2 = (Article) entityfactory.createDomainEntity("article");
		try {
			Number id = articledao.insert(article);
			Number id2 = articledao.insert(article2);
			Assert.assertNotNull(id);
			Assert.assertNotNull(id2);
			Assert.assertEquals(article.getDate(), ((Article) articledao.select(id)).getDate());
			Assert.assertEquals(article2.getContent(), ((Article) articledao.select(id2)).getContent());
			article.setId((Long) id);
			article2.setId((Long) id2);
			articledao.delete(article);
			articledao.delete(article2);
		} catch (Exception e) {
		}
		LOGGER.info("select - end.");
	}

	@Test
	public void update() {
		LOGGER.info("update - starting...");
		Article article = (Article) entityfactory.createDomainEntity("article");
		Number id = articledao.insert(article);
		article.setId((Long) id);
		article.setAutor("updated");
		article.setTitle("updated");
		try {
			articledao.update(article);
			Assert.assertEquals("updated", ((Article) articledao.select(id)).getTitle());
			Assert.assertEquals("updated", ((Article) articledao.select(id)).getAutor());
			articledao.delete(article);
		} catch (Exception e) {
		}
		LOGGER.info("update - end.");
	}

	@Test(expectedExceptions = { ObjectNotFoundException.class })
	public void delete() throws ObjectNotFoundException {
		LOGGER.info("delete - starting...");
		Article article = (Article) entityfactory.createDomainEntity("article");
		Number id = articledao.insert(article);
		article.setId((Long) id);
		articledao.delete(article);
		articledao.select(id);
		LOGGER.info("delete - end.");
	}

	@Test
	public void selectAll() {
		LOGGER.info("selectAll - starting...");
		Article article = (Article) entityfactory.createDomainEntity("article");
		Article article2 = (Article) entityfactory.createDomainEntity("article");
		Number id = articledao.insert(article);
		Number id2 = articledao.insert(article2);
		Assert.assertFalse(articledao.selectAll().isEmpty());
		Assert.assertEquals(2, articledao.selectAll().size());
		article.setId((Long) id);
		article2.setId((Long) id2);
		articledao.delete(article);
		articledao.delete(article2);
		LOGGER.info("selectAll - end.");
	}

	@Test
	public void selectByMember() {
		LOGGER.info("selectByMember - starting...");
		Article article = (Article) entityfactory.createDomainEntity("article");
		Number id = articledao.insert(article);
		List<DomainEntity> listArt = articledao.selectByMember(article.getMember());
		Assert.assertEquals(article.getDate(), ((Article) listArt.get(0)).getDate());
		article.setId((Long) id);
		articledao.delete(article);
		LOGGER.info("selectByMember - end.");
	}

	@Test
	public void selectByCategory() {
		LOGGER.info("selectByArticle - starting...");
		Article article = (Article) entityfactory.createDomainEntity("article");
		Number id = articledao.insert(article);
		List<DomainEntity> listArt = articledao.selectByCategory(article.getCategory());
		Assert.assertEquals(article.getTitle(), ((Article) listArt.get(0)).getTitle());
		article.setId((Long) id);
		articledao.delete(article);
		LOGGER.info("selectByArticle - end.");
	}

	@Test
	public void selectByKey() {
		LOGGER.info("selectByKey - starting...");
		Article article = (Article) entityfactory.createDomainEntity("article");
		Number id = articledao.insert(article);
		List<DomainEntity> listArt = articledao.selectByKey(article.getTitle());
		Assert.assertEquals(article.getTitle(), ((Article) listArt.get(0)).getTitle());
		article.setId((Long) id);
		articledao.delete(article);
		LOGGER.info("selectByKey - end.");
	}

	// ====================Cache Testing===============================

	@Test
	public void selectCachedElement() {
		LOGGER.info("selectCachedElement - starting...");
		Article article = (Article) entityfactory.createDomainEntity("article");
		Number id = articledao.insert(article);
		article.setId((Long) id);
		articledao.insertToCache(article);
		Assert.assertEquals(article.getTitle(), ((Article) articledao
		        .selectCachedElement((Long) id,Article.class.getCanonicalName())).getTitle());
		articledao.delete(article);
		LOGGER.info("selectCachedElement - end.");
	}

	@Test
	public void insertToCache() {
		LOGGER.info("insertToCache - starting...");
		Article article = (Article) entityfactory.createDomainEntity("article");
		Article article2 = (Article) entityfactory.createDomainEntity("article");
		Number id = articledao.insert(article);
		Number id2 = articledao.insert(article2);
		article.setId((Long) id);
		article2.setId((Long) id2);
		articledao.insertToCache(article);
		articledao.insertToCache(article2);
		Assert.assertEquals(article.getTitle(), ((Article) articledao.selectCachedElement((Long) id, Article.class.getCanonicalName())).getTitle());
		Assert.assertEquals(article2.getContent(), ((Article) articledao.selectCachedElement((Long) id2, Article.class.getCanonicalName())).getContent());
		articledao.delete(article);
		articledao.delete(article2);
		LOGGER.info("insertToCache - end.");
	}

}
